﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SharePoint.Utilities;
using System.Web.UI.WebControls;
using System.Web.UI;
using Microsoft.SharePoint;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.HtmlControls;
namespace Easy.Announcement.EasyAnnIsotopeWebPart
{
    public class EasyAnnIsotopeEditorPart : EditorPart
    {
        private string e_listName;
        private string e_viewName;
        private string e_filterBy;
        private string e_sortBy;
        private Panel panel = null;
        private DropDownList listDDL = null;
        private DropDownList viewDDL = null;
        private DropDownList titleFieldDDL = null;
        private DropDownList publishDateFieldDDL = null;
        private DropDownList summaryFieldDDL = null;
        private DropDownList filterDDL = null;
        private ListBox sortbyLB = null;

        private const string e_emptyChoice = "(None)";
        protected override void OnInit(EventArgs e)
        {
            this.Title = "Easy Settings";

            e_listName = this.UniqueID + "_listName";
            e_viewName = this.UniqueID + "_viewName";
            e_filterBy = this.UniqueID + "_filterBy";
            e_sortBy = this.UniqueID + "_sortBy";

            panel = new Panel();
            listDDL = new DropDownList();
            listDDL.ID = "ListDDL";
            listDDL.Width = Unit.Percentage(100);
            List<string> lists = new List<string>();
            lists.Add(e_emptyChoice);
            lists.AddRange(SPContext.Current.Web.Lists.Cast<SPList>().Where(l => !l.Hidden).Select(l => l.Title).ToList());
            listDDL.DataSource = lists;
            listDDL.DataBind();
            listDDL.AutoPostBack = true;
            listDDL.SelectedIndexChanged += ListDDL_SelectedIndexChanged;

            e_appendHeader(panel, "List Settings");
            e_appendLabel(panel, "List Name", "");
            e_appendBody(panel, listDDL);


            if (!Initialised)
            {
                listDDL.SelectedValue = WebPart.ListName;
            }

            if (listDDL.SelectedValue != e_emptyChoice)
            {
                e_appendDottedLine(panel);
                e_renderControlBaseOnListName(panel, WebPart.ListName, false);
            }

            if (!Initialised)
            {
                if (!string.IsNullOrEmpty(WebPart.ViewName))
                {
                    viewDDL.SelectedValue = WebPart.ViewName;

                }

                if (!string.IsNullOrEmpty(WebPart.TitleField))
                {
                    titleFieldDDL.SelectedValue = WebPart.TitleField;
                }
                if (!string.IsNullOrEmpty(WebPart.PublishDateField))
                {
                    publishDateFieldDDL.SelectedValue = WebPart.PublishDateField;
                }
                if (!string.IsNullOrEmpty(WebPart.SummaryField))
                {
                    summaryFieldDDL.SelectedValue = WebPart.SummaryField;
                }
                if (!string.IsNullOrEmpty(WebPart.FilterByField))
                {
                    filterDDL.SelectedValue = WebPart.FilterByField;
                }

                if (!string.IsNullOrEmpty(WebPart.SortByFields))
                {

                    string[] sortByFields = WebPart.SortByFields.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string sortBy in sortByFields)
                    {
                        foreach (ListItem item in sortbyLB.Items)
                        {
                            if (item.Value == sortBy)
                            {
                                item.Selected = true;
                            }
                        }
                    }

                }
                Initialised = true;
            }

            this.Controls.Add(panel);
            base.OnInit(e);
        }

        public override bool ApplyChanges()
        {
            EnsureChildControls();
            WebPart.ListName = listDDL.SelectedValue;
            WebPart.ViewName = viewDDL.SelectedValue;
            WebPart.TitleField = titleFieldDDL.SelectedValue;
            WebPart.PublishDateField = publishDateFieldDDL.SelectedValue;
            WebPart.SummaryField = summaryFieldDDL.SelectedValue;

            string filterByValue = filterDDL.SelectedValue != e_emptyChoice ? filterDDL.SelectedValue : string.Empty;
            WebPart.FilterByField = filterByValue;
            if (sortbyLB.SelectedValue != e_emptyChoice)
            {
                WebPart.SortByFields = string.Empty;
                foreach (ListItem li in sortbyLB.Items)
                {
                    if (li.Selected)
                    {
                        WebPart.SortByFields += li.Value + ";";
                    }
                }
            }
            else
            {
                WebPart.SortByFields = string.Empty;
            }

            return true;
        }

        public override void SyncChanges()
        {
            EnsureChildControls();
        }


        protected override void CreateChildControls()
        {
            this.Page.Header.Controls.Add(new LiteralControl("<style>.ms-TPBorder {border-spacing: 0px;width: 100%;}</style>"));
            base.CreateChildControls();
        }

        private void e_appendLabel(Panel panel, string text, string tooltip)
        {
            Label label = new Label() { Text = text, ToolTip = tooltip };
            Panel sectionPanel = new Panel() { CssClass = "UserSectionHead" };
            sectionPanel.Controls.Add(label);
            panel.Controls.Add(sectionPanel);

        }

        private void e_appendHeader(Panel panel, string text)
        {
            panel.Controls.Add(new LiteralControl("<h3>" + text + "</h3>"));
        }

        private void e_appendBody(Panel panel, Control ctrl)
        {
            Panel sectionPanel = new Panel() { CssClass = "UserSectionBody" };
            Panel groupPanel = new Panel() { CssClass = "UserControlGroup" };
            groupPanel.Controls.Add(ctrl);
            sectionPanel.Controls.Add(groupPanel);
            panel.Controls.Add(sectionPanel);
        }

        private void e_appendDottedLine(Panel panel)
        {
            panel.Controls.Add(new LiteralControl("<div style='width:100%' class='UserDottedLine'></div>"));
        }

        private void e_renderControlBaseOnListName(Panel panel, string listName, bool isCallback)
        {
            SPList list = SPContext.Current.Web.Lists[listName];

            e_loadDropDownList(ref viewDDL, "ViewDDL", "Views", list.Views.Cast<SPView>().Select(v => v.Title).ToList(), false);
            e_appendDottedLine(panel);


            List<string> titleFields = list.Fields.Cast<SPField>().Where(f => f.Type == SPFieldType.Text).Select(f => f.InternalName).ToList();
            List<string> publishDateFields = list.Fields.Cast<SPField>().Where(f => f.Type == SPFieldType.DateTime).Select(f => f.InternalName).ToList();
            List<string> summaryFields = list.Fields.Cast<SPField>().Where(f => f.Type == SPFieldType.Text || f.Type == SPFieldType.Note).Select(f => f.InternalName).ToList();

            if (!isCallback)
            {
                e_appendHeader(panel, "Field Mapping");
            }
            e_loadDropDownList(ref titleFieldDDL, "TitleFieldDDL", "Title Field", titleFields, false, "Only 'Single Line of Text' field will be displayed here");
            e_loadDropDownList(ref publishDateFieldDDL, "PublishDateFieldDDL", "Publish Date Field", publishDateFields, false, "Only 'DateTime' field will be displayed here");
            e_loadDropDownList(ref summaryFieldDDL, "SummaryFieldDDL", "Summary Field", summaryFields, false, "Only 'Single Line of Text' or 'Multiple Line of Text' field will be displayed here");
            e_appendDottedLine(panel);


            if (!isCallback)
            {
                e_appendHeader(panel, "Additional Option");
            }
            List<string> filterFields = list.Fields.Cast<SPField>().Where(f => f.Type == SPFieldType.Choice || f.Type == SPFieldType.MultiChoice).Select(f => f.InternalName).ToList();
            e_loadDropDownList(ref filterDDL, "FilterDDL", "Filter By", filterFields, true, "Only 'Choice' field will be used as Filter By.");

            List<string> sortbyFields = list.Fields.Cast<SPField>().Where(f => f.Sortable && !f.Hidden).Select(f => f.InternalName).ToList();
            e_loadListBox(ref sortbyLB, "SortByLB", "Sort By", sortbyFields, true, "You can select multiple Sort By field by hitting 'Ctrl' key.");

        }

        private void e_loadDropDownList(ref DropDownList listControl, string id, string title, List<string> choices, bool optional, string tooltip = "")
        {
            List<string> internalChoices = new List<string>();
            if (optional)
            {
                internalChoices.Add(e_emptyChoice);
            }

            internalChoices.AddRange(choices);

            if (listControl == null)
            {
                listControl = new DropDownList();
                listControl.ID = id;
                listControl.Width = Unit.Percentage(100);

                e_appendLabel(panel, title, tooltip);
                e_appendBody(panel, listControl);
            }
            try
            {
                listControl.DataSource = internalChoices;
                listControl.DataBind();
            }
            catch (ArgumentOutOfRangeException ex)
            {
                listControl.ClearSelection();
            }
        }

        private void e_loadListBox(ref ListBox listControl, string id, string title, List<string> choices, bool optional, string tooltip)
        {
            List<string> internalChoices = new List<string>();
            if (optional)
            {
                internalChoices.Add(e_emptyChoice);
            }

            internalChoices.AddRange(choices);

            if (listControl == null)
            {
                listControl = new ListBox();
                listControl.ID = id;
                listControl.Width = Unit.Percentage(100);
                listControl.SelectionMode = ListSelectionMode.Multiple;

                e_appendLabel(panel, title, tooltip);
                e_appendBody(panel, listControl);
            }
            try
            {
                listControl.DataSource = internalChoices;
                listControl.DataBind();
            }
            catch (ArgumentOutOfRangeException ex)
            {
                listControl.ClearSelection();
            }
        }

        public void ListDDL_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listDDL.SelectedValue != e_emptyChoice)
            {
                e_renderControlBaseOnListName(panel, listDDL.SelectedValue, true);
                filterDDL.Enabled = true;
                viewDDL.Enabled = true;
                sortbyLB.Enabled = true;
            }
            else
            {
                filterDDL.Enabled = false;
                viewDDL.Enabled = false;
                sortbyLB.Enabled = false;
            }
        }

        protected bool Initialised
        {
            get
            {
                if (ViewState["e_initialised"] == null)
                {
                    return false;
                }
                return bool.Parse(ViewState["e_initialised"].ToString());
            }
            set
            {
                if (value)
                {
                    ViewState["e_initialised"] = true;
                }
                else
                {
                    ViewState["e_initialised"] = null;
                }
            }
        }

        protected EasyAnnIsotopeWebPart WebPart { get { return (EasyAnnIsotopeWebPart)this.WebPartToEdit; } }
    }
}
